home *** CD-ROM | disk | FTP | other *** search
/ POINT Software Programming / PPROG1.ISO / pascal / swag / tsr.swg / 0029_Screen Scrool TSR.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1994-08-25  |  6.2 KB  |  207 lines

  1. {
  2. >Basically a function that allows me to have 3 lines at the top non scrollabl
  3. >(that I can change, the content of the lines), but so the stuff underthem
  4. >scrolles...
  5.  
  6. Well, when you don't like the way the BIOS scrolls the screen, change
  7. the BIOS!
  8.  
  9. Here's an interesting program that I just wrote for this purpose.  It
  10. installs a TSR-like program that interferes with the BIOS scroll-up
  11. routine and forces the top to be a variable you set.
  12.  
  13. While debugging the program, I ran into a bit of trouble with the way
  14. that TP handles interrupts.  If you notice, half of the ISR has turned
  15. into restoring the registers that TP trashes!
  16. }
  17. Uses Dos, Crt; {Crt only used by main pgm}
  18.  
  19. var
  20.   TopLine : byte;
  21.   OldInt  : Procedure;
  22.  
  23. {Procedure Catch is the actual ISR, filtering out BIOS SCROLL-UP commands, and
  24.  forcing the top of the scroll to be the value [TopLine] }
  25.  
  26. {$F+}
  27. procedure Catch(Flags, rCS, rIP, rAX, rBX, rCX, rDX, rSI, rDI, rDS, rES, rBP: Word); Interrupt;
  28. {  Procedure Catch; interrupt;}
  29.   begin {Catch}
  30.     asm
  31.       MOV  AX, Flags
  32.       SAHF
  33.       MOV  AX, rAX
  34.       MOV  BX, rBX
  35.       MOV  CX, rCX
  36.       MOV  DX, rDX
  37.       MOV  SI, rSI
  38.       MOV  DI, rDI
  39.       CMP  AH, 06
  40.       JNE  @Pass
  41.       CMP  CH, TopLine
  42.       JA   @Pass
  43.       MOV  CH, TopLine
  44.  
  45. @Pass:
  46.     end;
  47.     OldInt;          {Pass through to old handler}
  48.     asm
  49.       MOV  rAX, AX
  50.       MOV  rBX, BX
  51.       MOV  rCX, CX
  52.       MOV  rDX, DX
  53.       MOV  rSI, SI
  54.       MOV  rDI, DI
  55.     end;
  56.   end; {Catch}
  57. {$F-}
  58.  
  59.   Procedure Install;
  60.   begin
  61.     GetIntVec($10, Addr(OldInt));
  62.     SetIntVec($10, Addr(Catch));
  63.   end;
  64.  
  65.   Procedure DeInstall;
  66.   begin
  67.     SetIntVec($10, Addr(OldInt));
  68.   end;
  69.  
  70. begin
  71.   ClrScr;
  72.   DirectVideo := TRUE;
  73.   TopLine := 5; {Keep 5+1 lines at top of screen}
  74.   Install;
  75.   while true do readln;
  76. end.
  77.  
  78. {
  79. >p.p.s  I also need a routine (preferably in Turbo Pascal 7 ASM) that saves t
  80. >       content of the current screen in an ANSI file on the disk.  I saw one
  81. >       a while ago in SWAG, but I can't seem to find it now (I'm a dist site
  82. >       but still can't find it).
  83.  
  84. Also, since I didn't have anything better to do, I sat down and did a
  85. version of your screen->ANSI.  It's rather primitive... it does a 80x24
  86. dump with auto-EOLn seensing, does no CRLF if the line is 80 chars long
  87. (relies on screen wrap) and no macroing. If you want to, you can add
  88. macroing, which replaces a number of spaces with a single ANSI 'set
  89. cursor' command. Well, here goes...
  90.  
  91. }
  92.   Procedure Xlate(var OutFile : text); {by Erik Anderson}
  93.   {The screen is basically an array of elements, each element containing one
  94.    a one-byte character and a one-byte color attribute}
  95.   const
  96.     NUMROWS = 25;
  97.     NUMCOLS = 80;
  98.   type
  99.     ElementType = record
  100.                     ch   : char;
  101.                     Attr : byte;
  102.                   end;
  103.     ScreenType = array[1..NUMROWS,1..NUMCOLS] of ElementType;
  104.  
  105.   {The Attribute is structured as follows:
  106.     bit 0: foreground blue element
  107.     bit 1:     "      green element
  108.     bit 2:     "      red element
  109.     bit 3: high intensity flag
  110.     bit 4: background blue element
  111.     bit 5:     "      green element
  112.     bit 6:     "      red element
  113.     bit 7: flash flag
  114.  
  115.   The following constant masks help the program acess different parts
  116.   of the attribute}
  117.   const
  118.     TextMask = $07; {0000 0111}
  119.     BoldMask = $08; {0000 1000}
  120.     BackMask = $70; {0111 0000}
  121.     FlshMask = $80; {1000 0000}
  122.     BackShft = 4;
  123.  
  124.     ESC = #$1B;
  125.  
  126.   {ANSI colors are not the same as IBM colors... this table fixes the
  127.    discrepancy:}
  128.     ANSIcolors : array[0..7] of byte = (0, 4, 2, 6, 1, 5, 3, 7);
  129.  
  130.     {This procedure sends the new attribute to the ANSI dump file}
  131.     Procedure ChangeAttr(var Outfile : text; var OldAtr : byte; NewAtr : byte);
  132.     var
  133.       Connect : string[1]; {Is a seperator needed?}
  134.     begin
  135.       Connect := '';
  136.       write(Outfile, ESC, '['); {Begin sequence}
  137.       If (OldAtr AND (BoldMask+FlshMask)) <>     {Output flash & blink}
  138.          (NewAtr AND (BoldMask+FlshMask)) then begin
  139.         write(Outfile, '0');
  140.         If NewAtr AND BoldMask <> 0 then write(Outfile, ';1');
  141.         If NewAtr AND FlshMask <> 0 then write(Outfile, ';5');
  142.         OldAtr := $FF; Connect := ';';   {Force other attr's to print}
  143.       end;
  144.  
  145.       If OldAtr AND BackMask <> NewAtr AND BackMask then begin
  146.         write(OutFile, Connect,
  147.               ANSIcolors[(NewAtr AND BackMask) shr BackShft] + 40);
  148.         Connect := ';';
  149.       end;
  150.  
  151.       If OldAtr AND TextMask <> NewAtr AND TextMask then begin
  152.         write(OutFile, Connect,
  153.               ANSIcolors[NewAtr AND TextMask] + 30);
  154.       end;
  155.  
  156.       write(outfile, 'm'); {Terminate sequence}
  157.       OldAtr := NewAtr;
  158.     end;
  159.  
  160.     {Does this character need a changing of the attribute?  If it is a space,
  161.      then only the background color matters}
  162.  
  163.     Function AttrChanged(Attr : byte; ThisEl : ElementType) : boolean;
  164.     var
  165.       Result : boolean;
  166.     begin
  167.       Result := FALSE;
  168.       If ThisEl.ch = ' ' then begin
  169.         If ThisEl.Attr AND BackMask <> Attr AND BackMask then
  170.           Result := TRUE;
  171.       end else begin
  172.         If ThisEl.Attr <> Attr then Result := TRUE;
  173.       end;
  174.       AttrChanged := Result;
  175.     end;
  176.  
  177.   var
  178.     Screen   : ScreenType absolute $b800:0000;
  179.     ThisAttr, TestAttr : byte;
  180.     LoopRow, LoopCol, LineLen : integer;
  181.   begin {Xlate}
  182.     ThisAttr := $FF; {Force attribute to be set}
  183.     For LoopRow := 1 to NUMROWS do begin
  184.  
  185.       LineLen := NUMCOLS;   {Find length of line}
  186.       While (LineLen > 0) and (Screen[LoopRow, LineLen].ch = ' ')
  187.             and not AttrChanged($00, Screen[LoopRow, LineLen])
  188.         do Dec(LineLen);
  189.  
  190.       For LoopCol := 1 to LineLen do begin {Send stream to file}
  191.         If AttrChanged(ThisAttr, Screen[LoopRow, LoopCol])
  192.           then ChangeAttr(Outfile, ThisAttr, Screen[LoopRow, LoopCol].Attr);
  193.         write(Outfile, Screen[LoopRow, LoopCol].ch);
  194.       end;
  195.     If LineLen < 80 then writeln(OutFile); {else wraparound occurs}
  196.     end;
  197.   end; {Xlate}
  198.  
  199. var
  200.   OutFile : text;
  201. begin
  202.   Assign(OutFile, 'dump.scn');
  203.   Rewrite(OutFile);
  204.   Xlate(OUtFile);
  205.   Close(OUtFile);
  206. end.
  207.